import time
import xlrd,xlwt
import PyPDF2

from forms.config import app_dist,basePath,basefileNames
from forms.component import 管理窗口_基类,筛选条件_窗体,导入_显示_基类
from PyQt5.QtWidgets import QApplication,QWidget,QMessageBox,QFileDialog,QAction,QLineEdit,QFrame,QMenu,QTableWidgetItem
from PyQt5.QtGui import QDoubleValidator,QIntValidator
from PyQt5.Qt import QDate,QSizePolicy,QSize,QDateTime,QIcon,QFont,Qt
import sys,os,openpyxl
import win32api,win32print
from win32com import client
from PIL import Image
import img2pdf
from forms import  质量标准
from forms.component.db import 操作_sql
from forms.component.查询_窗体 import 查询_基类_窗体
from forms.component.单击的lable控件 import MyQLabel
from forms.component.打印机_窗体 import 打印机_基类_窗体
class 资料打印_管理_窗体(管理窗口_基类):
    def __init__(self,app=None):
        self.app = app
        super().__init__()
        self.subwindow = self.app.ui.mdiArea.addSubWindow(self)
        self.localInit()


    # def __new__(cls, *args, **kwargs):
    #     '''实现单例模式'''
    #     if not hasattr(cls,'_instance'):
    #         #_instance属性中存储的就是单例
    #         cls._instance=super().__new__(cls, *args, **kwargs)
    #     else:
    #         '''有实例的时候'''
    #         cls._instance.app.ui.mdiArea.setActiveSubWindow(cls._instance.subwindow)
    #         cls._instance.app.ui.mdiArea.closeActiveSubWindow()
    #         cls._instance.app.ui.mdiArea.removeSubWindow(cls._instance)
    #         cls._instance = super().__new__(cls, *args, **kwargs)
    #     return cls._instance
    def localInit(self):
        self.ui.toolButton_7.setVisible(False)#仅显示生产品种
        self.ui.toolButton_8.setVisible(False)#仅显示分包
        self.ui.toolButton_9.setVisible(False) #筛选条件
        self.ui.toolButton_4.setText('打印质量标准')
        self.ui.toolButton.setText('打印首营标签')
        self.ui.toolButton_2.setText('打印质检报告')
        self.ui.toolButton_3.setText('打印全部')
        self.ui.toolButton_5.setVisible(False)
        self.ui.toolButton_11.setVisible(False)
        self.tableWidgetInit()
        self.ui.pushButton.setVisible(False)
        self.ui.pushButton_3.setVisible(False)
        self.ui.pushButton_4.setVisible(False)
        self.ui.pushButton_5.setVisible(False)
        self.ui.pushButton_2.setVisible(False)
        self.ui.pushButton_6.setVisible(False)
        self.ui.pushButton_7.setVisible(False)
        self.ui.label.setVisible(False)
        self.ui.label_3.setVisible(False)
        self.ui.label_4.setVisible(False)
        self.ui.comboBox.setVisible(False)
        self.ui.comboBox_2.setVisible(False)
        self.ui.lineEdit.setVisible(False)

    def tableWidgetInit(self):

        for i in range(self.ui.tableWidget.rowCount()):
            self.ui.tableWidget.setRowHidden(i, False)
        self.ui.tableWidget.clear()
        self.ui.tableWidget.setSortingEnabled(False)
        time.sleep(1)
        # 设置两行间隔色
        self.ui.tableWidget.setAlternatingRowColors(True)
        fileds=['品名','批号','包装规格','标签装量','标签数量','规格','产地','保质期','生产日期','执行标准']

        self.ui.tableWidget.setColumnCount(len(fileds))

        # 设置表头
        self.ui.tableWidget.setHorizontalHeaderLabels(fileds)


        # 升降序排序
        self.ui.tableWidget.setSortingEnabled(True)
        # #设置列宽
        # self.ui.tableWidget.setColumnWidth(0,300)
        # 设置列宽自适应
        self.ui.tableWidget.resizeColumnsToContents()

    def _generateMenu(self, textedit, pos):
        # print(pos)
        # 转换屏幕的坐标系

        screenPos = self.sender().mapToGlobal(pos)
        colNum, rowNum = -1, -1
        for i in self.ui.tableWidget.selectionModel().selection().indexes():
            colNum = i.column()
            rowNum = i.row()
        # print('选中的单元格', i.column(), i.row())
        # if colNum == 6:
        tabWidget_menu = QMenu()

        sb_item_2 = tabWidget_menu.addAction("新增一行")
        sb_item_3 = tabWidget_menu.addAction("删除一行")
        sb_item_4 = tabWidget_menu.addAction("打印选中行质检报告")
        sb_item_5 = tabWidget_menu.addAction("打印选中行标签")
        sb_item_6 = tabWidget_menu.addAction("打印选中行质量标准")
        sb_item_7 = tabWidget_menu.addAction("打印选中行所有资料")
        sb_item = tabWidget_menu.addAction("导出数据-Excel")
        tabWidget_action = tabWidget_menu.exec(screenPos)  # 右键执行
        if tabWidget_action == sb_item:
            self.dataToExcel()
        if tabWidget_action == sb_item_2:
            self._table_New_row(rowNum + 1)
        elif tabWidget_action == sb_item_3:
            self.ui.tableWidget.removeRow(rowNum)
        elif tabWidget_action == sb_item_5:
            self.printSelctBQRePort(rowNum)
        elif tabWidget_action == sb_item_4:
            self.printSelctZJRePort(rowNum)
        elif tabWidget_action == sb_item_6:
            self.printSelctZLStandard(rowNum)
        elif tabWidget_action == sb_item_7:
            self.printSelctAll(rowNum)
    def getRowData(self,rowNum):
        if rowNum==None: #获取所有数据
            getDatas = []
            for rowNum in range(self.ui.tableWidget.rowCount()):
                try:
                    品名 = self.ui.tableWidget.cellWidget(rowNum, 0).text()
                except:
                    品名 = ''
                try:
                    批号 = self.ui.tableWidget.item(rowNum, 1).text()
                except:
                    批号 = ''
                try:
                    包装规格 = self.ui.tableWidget.item(rowNum, 2).text()
                except:
                    包装规格 = ''
                try:
                    标签装量 = self.ui.tableWidget.item(rowNum, 3).text()
                except:
                    标签装量 = ''
                try:
                    标签数量 = self.ui.tableWidget.item(rowNum, 4).text()
                except:
                    标签数量 = ''
                try:
                    规格 = self.ui.tableWidget.item(rowNum, 5).text()
                except:
                    规格 = ''
                try:
                    产地 = self.ui.tableWidget.item(rowNum, 6).text()
                except:
                    产地 = ''
                try:
                    保质期 = self.ui.tableWidget.item(rowNum, 7).text()
                except:
                    保质期 = ''
                try:
                    生产日期 = self.ui.tableWidget.item(rowNum, 8).text()
                except:
                    生产日期 = ''
                try:
                    执行标准 = self.ui.tableWidget.item(rowNum, 9).text()
                except:
                    执行标准 = ''
                getDatas.append( [品名, 批号, 包装规格, 标签装量, 标签数量, 规格, 产地, 保质期, 生产日期, 执行标准])
            # print(getDatas)
            return getDatas
        else:
            try:品名=self.ui.tableWidget.cellWidget(rowNum,0).text()
            except:品名=''
            try:     批号=self.ui.tableWidget.item(rowNum,1).text()
            except:  批号=''
            try:     包装规格=self.ui.tableWidget.item(rowNum,2).text()
            except:  包装规格=''
            try:     标签装量=self.ui.tableWidget.item(rowNum,3).text()
            except:  标签装量=''
            try:     标签数量=self.ui.tableWidget.item(rowNum,4).text()
            except:  标签数量=''
            try:     规格=self.ui.tableWidget.item(rowNum,5).text()
            except:  规格=''
            try:     产地=self.ui.tableWidget.item(rowNum,6).text()
            except:  产地=''
            try:     保质期=self.ui.tableWidget.item(rowNum,7).text()
            except:  保质期=''
            try:     生产日期=self.ui.tableWidget.item(rowNum,8).text()
            except:  生产日期=''
            try:     执行标准=self.ui.tableWidget.item(rowNum,9).text()
            except:  执行标准=''
            return [品名,批号,包装规格,标签装量,标签数量,规格,产地,保质期,生产日期,执行标准]
    def printSelctAll(self,rowNum):
        if rowNum==-1:
            return
        else:
            try:
                品名=self.ui.tableWidget.cellWidget(rowNum,0).text()
                if not 品名:
                    QMessageBox.information(self, '提示', '选中的行品名错误')
                    return
            except:
                QMessageBox.information(self, '提示', '选中的行品名错误')
                return

            try:
                执行标准=self.ui.tableWidget.item(rowNum,9).text()
            except:
                QMessageBox.information(self, '提示', '选中的行执行标准错误')
                return
            try:
                批号=self.ui.tableWidget.item(rowNum,1).text()
            except:
                QMessageBox.information(self, '提示', '选中的行批号错误')
                return
            try:
                标签装量=self.ui.tableWidget.item(rowNum,3).text()
            except:
                QMessageBox.information(self, '提示', '选中的行标签装量错误')
                return
            try:
                标签数量=int(self.ui.tableWidget.item(rowNum,4).text())
            except:
                QMessageBox.information(self, '提示', '选中的行标签数量错误')
                return
            try:
                规格=self.ui.tableWidget.item(rowNum,5).text()
            except:
                QMessageBox.information(self, '提示', '选中的行规格错误')
                return
            try:
                产地=self.ui.tableWidget.item(rowNum,6).text()
            except:
                QMessageBox.information(self, '提示', '选中的行产地错误')
                return
            try:
                保质期=int(self.ui.tableWidget.item(rowNum,7).text())
            except:
                QMessageBox.information(self, '提示', '选中的行保质期错误')
                return
            try:
                执行标准=self.ui.tableWidget.item(rowNum,9).text()
            except:
                QMessageBox.information(self, '提示', '选中的行执行标准错误')
                return
            try:
                生产日期=QDate.fromString(self.ui.tableWidget.item(rowNum,7).text(),'yyyy-MM-dd')
            except:
                QMessageBox.information(self, '提示', '选中的行生产日期错误')
                return
            self.打印 = 打印机_基类_窗体(type='打印全部')
            self.打印.show()  # 直接打印
            self.打印.ui.pushButton.clicked.connect(lambda :self.PrintOK(type='打印全部',data=[self.getRowData(rowNum)]))
            self.打印.ui.pushButton_2.clicked.connect(
                lambda: self.PrintOK(type='打印全部预览', data=[self.getRowData(rowNum)]))
    def printSelctBQRePort(self,rowNum):
        if rowNum==-1:
            return
        else:
            try:
                品名=self.ui.tableWidget.cellWidget(rowNum,0).text()
                if not 品名:
                    QMessageBox.information(self, '提示', '选中的行品名错误')
                    return
            except:
                QMessageBox.information(self, '提示', '选中的行品名错误')
                return
            try:
                执行标准=self.ui.tableWidget.item(rowNum,9).text()
            except:
                QMessageBox.information(self, '提示', '选中的行执行标准错误')
                return
            try:
                批号=self.ui.tableWidget.item(rowNum,1).text()
            except:
                QMessageBox.information(self, '提示', '选中的行批号错误')
                return
            try:
                标签装量=self.ui.tableWidget.item(rowNum,3).text()
            except:
                QMessageBox.information(self, '提示', '选中的行标签装量错误')
                return
            try:
                标签数量=int(self.ui.tableWidget.item(rowNum,4).text())
            except:
                QMessageBox.information(self, '提示', '选中的行标签数量错误')
                return
            try:
                规格=self.ui.tableWidget.item(rowNum,5).text()
            except:
                QMessageBox.information(self, '提示', '选中的行规格错误')
                return
            try:
                产地=self.ui.tableWidget.item(rowNum,6).text()
            except:
                QMessageBox.information(self, '提示', '选中的行产地错误')
                return
            try:
                保质期=int(self.ui.tableWidget.item(rowNum,7).text())
            except:
                QMessageBox.information(self, '提示', '选中的行保质期错误')
                return
            try:
                执行标准=self.ui.tableWidget.item(rowNum,9).text()
            except:
                QMessageBox.information(self, '提示', '选中的行执行标准错误')
                return
            try:
                生产日期=QDate.fromString(self.ui.tableWidget.item(rowNum,7).text(),'yyyy-MM-dd')
            except:
                QMessageBox.information(self, '提示', '选中的行生产日期错误')
                return
            self.打印 = 打印机_基类_窗体(type='打印标签')
            self.打印.show()  # 直接打印
            self.打印.ui.pushButton.clicked.connect(lambda :self.PrintOK(type='打印标签',data=[self.getRowData(rowNum)]))
            self.打印.ui.pushButton_2.clicked.connect(
                lambda: self.PrintOK(type='打印标签预览', data=[self.getRowData(rowNum)]))
    def printSelctZLStandard(self,rowNum):
        if rowNum==-1:
            return
        else:
            try:
                品名=self.ui.tableWidget.cellWidget(rowNum,0).text()
                if not 品名:
                    QMessageBox.information(self, '提示', '选中的行品名错误')
                    return
            except:
                QMessageBox.information(self, '提示', '选中的行品名错误')
                return
            try:
                执行标准=self.ui.tableWidget.item(rowNum,9).text()
            except:
                QMessageBox.information(self, '提示', '选中的行执行标准错误')
                return
            self.打印 = 打印机_基类_窗体(type='打印质量标准')
            self.打印.show()  # 直接打印
            self.打印.ui.pushButton.clicked.connect(lambda :self.PrintOK(type='打印质量标准',data=[self.getRowData(rowNum)]))
            self.打印.ui.pushButton_2.clicked.connect(
                lambda: self.PrintOK(type='打印质量标准预览', data=[self.getRowData(rowNum)]))
    def printSelctZJRePort(self,rowNum):
        # print('dayin',rowNum)
        if rowNum==-1:
            return
        else:
            try:
                品名=self.ui.tableWidget.cellWidget(rowNum,0).text()
                if not 品名:
                    QMessageBox.information(self, '提示', '选中的行品名错误')
                    return
            except:
                QMessageBox.information(self, '提示', '选中的行品名错误')
                return
            try:
                批号=self.ui.tableWidget.item(rowNum,1).text()
            except:
                QMessageBox.information(self, '提示', '选中的行批号错误')
                return
            self.打印 = 打印机_基类_窗体(type='打印质检报告')
            self.打印.show()  # 直接打印
            self.打印.ui.pushButton.clicked.connect(lambda :self.PrintOK(type='打印质检报告',data=[self.getRowData(rowNum)]))
            self.打印.ui.pushButton_2.clicked.connect(
                lambda: self.PrintOK(type='打印质检报告预览', data=[self.getRowData(rowNum)]))
    def PrintOK(self,type,data):
        filename,printer='',''
        if '打印质检报告' in type:
            filename ,noprintNames= self.getZJreport(data)
            printer=self.打印.ui.comboBox_4.currentText()
            if noprintNames:
                self.lostMSG(['品名','批号'],noprintNames,'质检报告')
            self.printPrint(printer,filename,type)
        elif '打印质量标准'in type:
            filename,noprintNames = self.getZLstandard(data)
            printer = self.打印.ui.comboBox.currentText()
            if noprintNames:
                self.lostMSG(['品名','执行标准'],noprintNames,'质量标准')
            self.printPrint(printer, filename,type)
        elif  '打印标签' in type:
            self.getBQReport(data,type)
            self.打印.close()
            return
        if '打印全部' in type:
            filename1  ,noprintNames= self.getZJreport(data)
            printer1=self.打印.ui.comboBox_4.currentText()


            filename2 ,noprintZLNames= self.getZLstandard(data)
            printer2 = self.打印.ui.comboBox.currentText()
            items=[]
            for it in  noprintNames:
                items.append(it)
            for it in noprintZLNames:
                items.append(it)
            if items:
                self.lostMSG(['品名','批号/执行标准'],items,'质检报告/质量标准')
            self.printPrint(printer1, filename1, type)
            self.printPrint(printer2, filename2,type)


            self.getBQReport(data,type)
            self.打印.close()

    def printPrint(self,printer,filename,type):

        if type=='打印质检报告预览' or type=='打印质量标准预览'or type=='打印全部预览':
            if filename:
                os.startfile(filename)  # 加载打印模板 # 打印预览
            self.打印.close()
            return

        win32print.SetDefaultPrinter(printer)
        self.打印.close()
        if filename:
            try:
                win32api.ShellExecute(
                    0,
                    "print",
                    filename,
                    '/d:"%s"' % win32print.GetDefaultPrinter(),
                    ".",
                    0
                )
            except Exception as e:
                QMessageBox.information(self, '提示', f'打印错误：{e}')
    def getBQReport(self,data,type):
        # 创建打印数据
        parms, fileds_items, subreport_parms, subreport_fileds_items = {}, [], {}, []
        for da in data:
            for i in range(int(da[4])):
                fileds_items.append({'品名': da[0], '批号': da[1], '包装规格': da[2],
                                     '标签装量': da[3], '标签数量': da[4],
                                     '规格': da[5], '产地': da[6], '保质期': da[7],
                                     '生产日期': da[8], '执行标准': da[9]})

        try:
            path = os.path.join(basePath,'report','资料打印','总报表', self.打印.ui.comboBox_2.currentText() + '.grf')
            Report = client.Dispatch("gregn.GridppReport.6")  # 是com组件，engine

            if os.path.exists(path):
                Report.LoadFromFile(path)  # 加载打印模板
                Report.PrepareLoadData()  # 推模式，此语句要在前面定义好，表示不用数据库的数据
                # 创建打印数据
                # parms, fileds_items, subreport_parms, subreport_fileds_items = self.print_get_data()
                if subreport_parms or subreport_fileds_items:
                    SubReport = Report.ControlByName("SubReport1").AsSubReport.Report  # 子报表
                    SubReport.PrepareLoadData()
                    if subreport_parms:
                        for k, v in parms.items():
                            if v == None:
                                v = ''
                            SubReport.ParameterByName(k).AsString = str(v)
                    if subreport_fileds_items:
                        for subreport_fileds_item in subreport_fileds_items:
                            SubReport.DetailGrid.Recordset.Append()  # 添加字段值的开始
                            for k, v in subreport_fileds_item.items():
                                if v == None:
                                    v = ''
                                SubReport.FieldByName(k).AsString = str(v)  # 对字段赋值
                            SubReport.DetailGrid.Recordset.Post()  # 添加字段值的结束
                if parms or fileds_items:
                    if parms:
                        for k, v in parms.items():
                            if v == None:
                                v = ''
                            Report.ParameterByName(k).AsString = str(v)
                    if fileds_items:
                        for fileds_item in fileds_items:
                            Report.DetailGrid.Recordset.Append()  # 添加字段值的开始
                            for k, v in fileds_item.items():
                                if v == None:
                                    v = ''

                                Report.FieldByName(k).AsString = str(v)  # 对字段赋值
                            Report.DetailGrid.Recordset.Post()  # 添加字段值的结束
                printer = self.打印.ui.comboBox_3.currentText()

                Report.Printer.PrinterName=printer


                if '预览' in type:
                    Report.PrintPreview(True)  # 打印预览
                else:
                    Report.Print(False)  # 直接打印


            else:
                # print("找不到相关报表")
                QMessageBox.information(self, '提示', '找不到相关报表')
        except Exception as e:
            QMessageBox.information(self, "提示", f"错误{e}")

    def getZLstandard(self,data):
        '''获取质量标准，先下载出来质量标准，然后在转换到一个pdf里面'''
        printFiles = []  # [[文件路径]]
        noPrintFiles=[]
        for da in data:
            品名=da[0]
            执行标准=da[9]
            sql=f"""select 文件名称,文件附件 from 质量标准_附件 where 质量标准_编号 in 
                    (select 编号 from 质量标准 where 品名='{品名}' and 执行标准='{执行标准}') """
            bool, mesg, data, fileds = 操作_sql().query_one(sql)

            if bool and data:
                for i in range(len(data)):
                    current_select_dist = {}
                    for k, v in zip(fileds, data[i]):
                        if v == None:
                            v = ''
                        current_select_dist[k] = v
                    path = os.path.join(basePath, "temp", current_select_dist[f'文件名称'])
                    with open(path, 'wb') as file:
                        file.write(current_select_dist[f'文件附件'])
                    printFiles.append(path)
            else:
                noPrintFiles.append([品名,执行标准])


        # 把img 图片转成pdf ，然后集合到一个pdf里
        pdfFiles = []
        for printfile in printFiles:
            # 获取文件后缀名
            dirpath, file_name = os.path.split(printfile)
            name, ext = os.path.splitext(file_name)
            if ext == '.jpg':

                pdf_path = os.path.join(basePath, 'temp', name + ".pdf")
                with Image.open(printfile) as image:

                    pdf_bytes = img2pdf.convert(printfile)
                    with open(pdf_path, "wb") as file:
                        file.write(pdf_bytes)
                pdfFiles.append(pdf_path)
            elif ext == ".pdf":
                pdfFiles.append(printfile)
        pdfMerge = PyPDF2.PdfMerger()
        pdfMergePath = os.path.join(basePath, 'temp', "2.pdf")
        if not pdfFiles:
            return None,noPrintFiles
        for pdf in pdfFiles:
            with open(pdf, 'rb') as pdffile:
                pdfMerge.append(PyPDF2.PdfReader(pdffile))
        pdfMerge.write(pdfMergePath)
        return pdfMergePath,noPrintFiles


    def getZJreport(self,data):
        '''获取质检报告,并把质检报告都转换到一个pdf里面'''
        dir=app_dist.get('ZJReportPath')
        # fileNames= [] #[[文件名称,文件路径]]
        #
        # for root,dirs,files in os.walk(dir):
        #     for file in files:
        #         fileNames.append([file,os.path.join(root,file)])
        fileNames=basefileNames
        printFiles=[]
        noPrintFiles=[]
        for da in data:
            品名批号=str(da[0])+"成品"+str(da[1])
            # print(品名批号,data)
            isCheck=False
            for fileName in fileNames:
                if 品名批号 in fileName[0] and 品名批号 :
                    #要判断是白芍241001 还是炒白芍241001,判断fileName[0] 匹配前面的一个字符不是汉字
                    index=fileName[0].index(品名批号)

                    if index==0:
                        printFiles.append(fileName[1])
                        isCheck=True
                        break
                    else:
                        str1=fileName[0][index-1]
                        if ord('\u4e00') <= ord(str1) <= ord('\u9fff'): #判断是否为汉字
                            pass
                        else:
                            printFiles.append(fileName[1])
                            isCheck = True
                            break
            if not isCheck:
                noPrintFiles.append([str(da[0]),str(da[1])])

        #把img 图片转成pdf ，然后集合到一个pdf里
        pdfFiles=[]
        for printfile in printFiles:
            #获取文件后缀名
            dirpath,file_name=os.path.split(printfile)
            name,ext=os.path.splitext(file_name)
            if ext=='.jpg':

                pdf_path=os.path.join(basePath,'temp',name+".pdf")
                with Image.open(printfile) as image:

                    pdf_bytes=img2pdf.convert(printfile)
                    with open(pdf_path,"wb") as file:
                        file.write(pdf_bytes)
                pdfFiles.append(pdf_path)
            elif ext==".pdf":
                pdfFiles.append(printfile)
        pdfMerge=PyPDF2.PdfMerger()
        pdfMergePath=os.path.join(basePath,'temp',"1.pdf")
        if not pdfFiles:
            return None,noPrintFiles
        for pdf in pdfFiles:
            with open(pdf,'rb') as pdffile:
                pdfMerge.append(PyPDF2.PdfReader(pdffile))
        pdfMerge.write(pdfMergePath)
        return pdfMergePath,noPrintFiles



    def _table_New_row(self, rowNum):
        # print(rowNum)
        self.ui.tableWidget.insertRow(rowNum)

        物料名称_Action = QAction(self)
        物料名称_Action.setIcon(QIcon(QIcon(os.path.join(basePath,'staticfiles','img','h16.png') )))
        lineedit = QLineEdit()
        lineedit.addAction(物料名称_Action, QLineEdit.TrailingPosition)  # 将该Action放到最右边
        物料名称_Action.triggered.connect(lambda: self._lookup_zBOM(rowNum=rowNum))
        lineedit.returnPressed.connect(lambda: self._lookup_zBOM(rowNum=rowNum))

        self.ui.tableWidget.setCellWidget(rowNum, 0, lineedit)
        lineedit.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        lineedit.customContextMenuRequested.connect(lambda: self._generateMenu(lineedit,lineedit.pos()))
        # lineedit.returnPressed.connect(self._lookup)
    def _lookup_zBOM(self, rowNum):
        '''# 查询未请验的品种  # 仓库管理_饮片_原料库
        先判断是正常检验还是复检请验
        生产管理_饮片_生产车间一_主BOM 生产管理_食品_生产车间_主BOM
        基础信息_饮片一车间_半成品     基础信息_食品车间_半成品
        '''
        # 仓库管理_饮片_原料库_入库退货管理{'_'.join(self.tableName.split('_')[:-1])}
        sql = f"""select 品名,批号,标签装量,执行标准,批量,单位,产地,规格,包装规格,生产日期,生产属性,保质期,备注 from 产品信息"""

        self.查询 = 查询_基类_窗体(lineedit_text=self.ui.tableWidget.cellWidget(rowNum, 0).text(), sql=sql)
        self.查询.show()
        self.查询.ui.tableWidget.doubleClicked.connect(lambda: self._cx_tablewidget_DbClicked_zBOM(rowNum=rowNum))

    def _cx_tablewidget_DbClicked_zBOM(self, rowNum):
        # print(self.ui.tableWidget.currentRow())
        # print(self.ui.tableWidget.horizontalHeaderItem(0).text())
        db_clicked_dist = {}
        for i in range(self.查询.ui.tableWidget.columnCount()):
            db_clicked_dist[self.查询.ui.tableWidget.horizontalHeaderItem(i).text()] = self.查询.ui.tableWidget.item(
                self.查询.ui.tableWidget.currentRow(), i).text()

        self.ui.tableWidget.cellWidget(rowNum, 0).setText(str(db_clicked_dist.get('品名')))
        self.ui.tableWidget.setItem(rowNum, 1, QTableWidgetItem(str(db_clicked_dist.get('批号'))))
        self.ui.tableWidget.setItem(rowNum, 2, QTableWidgetItem(str(db_clicked_dist.get('包装规格'))))
        self.ui.tableWidget.setItem(rowNum, 3, QTableWidgetItem(str(db_clicked_dist.get('标签装量'))))
        self.ui.tableWidget.setItem(rowNum, 4, QTableWidgetItem(str('1')))
        self.ui.tableWidget.setItem(rowNum, 5, QTableWidgetItem(str(db_clicked_dist.get('规格'))))
        self.ui.tableWidget.setItem(rowNum, 6, QTableWidgetItem(str(db_clicked_dist.get('产地'))))
        self.ui.tableWidget.setItem(rowNum, 7, QTableWidgetItem(str(db_clicked_dist.get('保质期'))))
        self.ui.tableWidget.setItem(rowNum, 8, QTableWidgetItem(str(db_clicked_dist.get('生产日期'))))
        self.ui.tableWidget.setItem(rowNum, 9, QTableWidgetItem(str(db_clicked_dist.get('执行标准'))))
        self.ui.tableWidget.editItem(self.ui.tableWidget.item(rowNum, 4))
        self.ui.tableWidget.item(rowNum, 4).setSelected(True)

        self.查询.close()

    def parmsInit(self):
        self.tableName = '资料打印'

    def ShowChanged(self):
        self.show_class = self.sender().objectName()
        self.ui.label_6.setText(f'当前选择的显示类型为{self.sender().text()}')
        if self.show_class=='toolButton_7':
            self.search_text['生产属性']='生产'
        else:
            self.search_text['生产属性'] = '分包'
        self.显示查询数据()
    def SearchChanged(self):
        sql = ''
        sql = f"select * from {self.tableName} "

        self.筛选条件 = 筛选条件_窗体(sql=sql, curr_app_page=self)
        self.筛选条件.show()
    def exportTemplateFile(self):
        '''导出文件模板'''
        pass

    def importFile(self):
        '''导入文件'''
        fileName, filetype = QFileDialog.getOpenFileName(self,
                                                         "选取文件",
                                                         ".././temp/",
                                                         "Text Files (*.xls);;Text Files (*.xlsx)")  # 设置文件扩展名过滤,注意用双分号间隔

        # print(fileName)
        if fileName:

            # 判断文件是EXCEL xlsx 还是xls,
            getData=[]  #从EXCEL获取的产品信息
            getDataId = []
            if os.path.splitext(fileName)[-1] == '.xlsx':
                workbook = openpyxl.load_workbook(fileName)
                worksheet = workbook.active
                for row in range(1, worksheet.max_row + 1):
                    if worksheet.cell(row, 2).value == '序号':
                        idRange = [row]
                    if '小计' in str(worksheet.cell(row, 2).value):
                        idRange.append(row)
                        getDataId.append(idRange)
                        idRange = []
                # print(getDataId)
                for id in getDataId:
                    for row in range(id[0] + 1, id[1]):
                        if worksheet.cell(row, 3).value:
                            # [品名，批号]
                            getData.append([worksheet.cell(row, 3).value, worksheet.cell(row, 10).value])

            elif os.path.splitext(fileName)[-1] == '.xls':


                # 打开文件
                workbook = xlrd.open_workbook(fileName)

                # 通过索引获取第一个工作表
                worksheet = workbook.sheet_by_index(0)

                for row_idx in range(worksheet.nrows):

                    if worksheet.cell_value(row_idx, 1) == '序号':
                        idRange = [row_idx]
                    if '小计' in str(worksheet.cell_value(row_idx, 1)):
                        idRange.append(row_idx)
                        getDataId.append(idRange)
                        idRange = []

                for id in getDataId:
                    for row in range(id[0] + 1, id[1]):
                        if worksheet.cell_value(row, 2):
                            # [品名，批号]
                            getData.append([worksheet.cell_value(row, 2), worksheet.cell_value(row, 9)])
                            # print(worksheet.cell_value(row, 2), worksheet.cell_value(row, 9))
            if not getData:
                QMessageBox.information(self, '提示', '未提取有效的数据')
                return
            else:
                sql=f"select 品名,批号,包装规格,标签装量,规格,产地,保质期,生产日期,执行标准 from 产品信息"
                bool, mesg, data, fileds = 操作_sql().query_one(sql)
                showData=[] #需要展示的内容
                noShowData=[]#未查到信息的内容
                if bool and data:

                    for item in getData: #item==[品名，批号]
                        isCheck=False
                        for da in data:

                            if str(item[0])==str(da[0]) and str(item[1])==str(da[1]):
                                showData.append(list(da))
                                isCheck=True
                        if not isCheck:
                            noShowData.append(item)
                if showData:
                    # self.ui.tableWidget.clear()
                    self.ui.tableWidget.setSortingEnabled(False)
                    self.ui.tableWidget.setRowCount(0)
                    # 设置行数
                    # self.ui.tableWidget.setRowCount(len(showData))
                    for i in range(len(showData)):
                        self._table_New_row(i)

                    # 添加数据
                    for item in showData:
                        item.insert(4,'1')
                    for i in range(len(showData)):
                        for j in range(len(showData[0])):
                            if j==0:
                                if showData[i][j] == None:
                                    self.ui.tableWidget.cellWidget(i, j).setText('')
                                else:
                                    self.ui.tableWidget.cellWidget(i, j).setText(str(showData[i][j]))
                                continue
                            if showData[i][j] == None:
                                self.ui.tableWidget.setItem(i, j, QTableWidgetItem(''))
                            else:
                                self.ui.tableWidget.setItem(i, j, QTableWidgetItem(str(showData[i][j])))

                else:
                    QMessageBox.information(self, '提示', '未匹配到数据库的产品信息')
                    # return
                if noShowData:

                    reply = QMessageBox.question(self, "提示",
                                                 f"""检测到有未匹配到数据库的产品信息，是否下载""",
                                                 QMessageBox.Yes | QMessageBox.No,
                                                 QMessageBox.Yes)

                    if reply == QMessageBox.Yes:
                        self.lostMSG(['品名','批号'],noShowData,'产品信息')
                    else:
                        pass
    def lostMSG(self,fileds,data,title):
        fileName, ok = QFileDialog.getSaveFileName(self, "文件导出",
                                                   ".././temp/{}".format(
                                                       title) + '未匹配' + QDateTime.currentDateTime().toString(
                                                       "yyyyMMddHHmmss"),
                                                   "Text Files (*.xlsx);;Text Files (*.xls)")

        if ok:


            # 判断文件是EXCEL xlsx 还是xls
            if os.path.splitext(fileName)[-1] == '.xlsx':
                workbook = openpyxl.Workbook(fileName)
                workbook.create_sheet(self.windowTitle())
                workbook.save(fileName)
                workbook = openpyxl.load_workbook(fileName)
                worksheet = workbook[self.windowTitle()]
                for i in range(len(fileds)):
                    worksheet.cell(1, i + 1, value=fileds[i])

                for i in range(len(data)):

                    for j in range(len(fileds)):
                        worksheet.cell(2 + i, j + 1, value=data[i][j])
                workbook.save(fileName)
            elif os.path.splitext(fileName)[-1] == '.xls':

                # 创建Workbook对象
                workbook = xlwt.Workbook()
                # 添加工作表
                worksheet = workbook.add_sheet(self.windowTitle())
                # 写入数据
                for i in range(len(fileds)):
                    worksheet.write(0, i, fileds[i])
                for i in range(len(data)):
                    for j in range(len(fileds)):
                        worksheet.write(1 + i, j, data[i][j])
                # 保存文件
                workbook.save(fileName)

            path = os.path.realpath(fileName)  # 获取的相对路径，并选中文件
            os.system(f'explorer /select,{path}')
    def print_get_data(self):
        '''打印报表所需要的数据
        parms: 参数集合
        fileds: 字段集合
        subreport_parms :子报表参数集合
        subreport_fileds:子报表字段集合
        '''
        parms, fileds_items, subreport_parms, subreport_fileds_items = {}, [], {}, []
        for rowNum in range(self.ui.tableWidget.rowCount()):
            try:
                品名 = self.ui.tableWidget.cellWidget(rowNum, 0).text()
            except:
                品名 = ''
            try:
                批号 = self.ui.tableWidget.item(rowNum, 1).text()
            except:
                批号 = ''
            try:
                包装规格 = self.ui.tableWidget.item(rowNum, 2).text()
            except:
                包装规格 = ''
            try:
                标签装量 = self.ui.tableWidget.item(rowNum, 3).text()
            except:
                标签装量 = ''
            try:
                标签数量 = self.ui.tableWidget.item(rowNum, 4).text()
            except:
                标签数量 = ''
            try:
                规格 = self.ui.tableWidget.item(rowNum, 5).text()
            except:
                规格 = ''
            try:
                产地 = self.ui.tableWidget.item(rowNum, 6).text()
            except:
                产地 = ''
            try:
                保质期 = self.ui.tableWidget.item(rowNum, 7).text()
            except:
                保质期 = ''
            try:
                生产日期 = self.ui.tableWidget.item(rowNum, 8).text()
            except:
                生产日期 = ''
            try:
                执行标准 = self.ui.tableWidget.item(rowNum, 9).text()
            except:
                执行标准 = ''
            fileds_items.append({'品名':品名, '批号':批号, '包装规格':批号,
                                 '标签装量':标签装量, '标签数量':标签数量,
                                 '规格':规格, '产地':产地, '保质期':保质期,
                                 '生产日期':生产日期, '执行标准':执行标准})



        return parms, fileds_items, subreport_parms,subreport_fileds_items
    def New_Btn_Clicked(self):
        '''打印质量标准'''
        if not self.ui.tableWidget.rowCount():
            QMessageBox.information(self, '提示', '没有数据')
            return
        else:
            for rowNum in range(self.ui.tableWidget.rowCount()):
                品名 = self.ui.tableWidget.cellWidget(rowNum, 0).text()
                if not 品名:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行品名错误')
                    return
                try:
                    执行标准 = self.ui.tableWidget.item(rowNum,9).text()
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行执行标准错误')
                    return
            self.打印 = 打印机_基类_窗体(type='打印质量标准')
            self.打印.show()  # 直接打印
            self.打印.ui.pushButton.clicked.connect(
                lambda: self.PrintOK(type='打印质量标准', data=self.getRowData(rowNum=None)))
            self.打印.ui.pushButton_2.clicked.connect(
                lambda: self.PrintOK(type='打印质量标准预览',data=self.getRowData(rowNum=None)))


    def Updata_Btn_Clicked(self):
        '''首营标签'''
        if not self.ui.tableWidget.rowCount():
            QMessageBox.information(self, '提示', '没有数据')
            return
        else:
            for rowNum in range(self.ui.tableWidget.rowCount()):
                品名 = self.ui.tableWidget.cellWidget(rowNum, 0).text()
                if not 品名:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行品名错误')
                    return
                品名 = self.ui.tableWidget.cellWidget(rowNum, 0).text()

                try:
                    执行标准 = self.ui.tableWidget.item(rowNum, 9).text()
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行执行标准错误')
                    return

                try:
                    批号 = self.ui.tableWidget.item(rowNum, 1).text()
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行批号错误')
                    return
                try:
                    标签装量 = self.ui.tableWidget.item(rowNum, 3).text()
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行错误')
                    return
                try:
                    标签数量 = int(self.ui.tableWidget.item(rowNum, 4).text())
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行错误')
                    return
                try:
                    规格 = self.ui.tableWidget.item(rowNum, 5).text()
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行错误')
                    return
                try:
                    产地 = self.ui.tableWidget.item(rowNum, 6).text()
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行错误')
                    return
                try:
                    保质期 = int(self.ui.tableWidget.item(rowNum, 7).text())
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行错误')
                    return
                try:
                    执行标准 = self.ui.tableWidget.item(rowNum, 9).text()
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行错误')
                    return
                try:
                    生产日期 = QDate.fromString(self.ui.tableWidget.item(rowNum, 7).text(), 'yyyy-MM-dd')
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行错误')
                    return
                self.打印 = 打印机_基类_窗体(type='打印标签')
                self.打印.show()  # 直接打印
                self.打印.ui.pushButton.clicked.connect(
                    lambda: self.PrintOK(type='打印标签', data=self.getRowData(rowNum=None)))
                self.打印.ui.pushButton_2.clicked.connect(
                    lambda: self.PrintOK(type='打印标签预览', data=self.getRowData(rowNum=None)))
    def Show_Btn_Clicked(self):
        '''打印质检报告'''

        if not self.ui.tableWidget.rowCount():
            QMessageBox.information(self, '提示', '没有数据')
            return
        else:
            for rowNum in range(self.ui.tableWidget.rowCount()):
                品名 = self.ui.tableWidget.cellWidget(rowNum, 0).text()
                if not 品名:
                    QMessageBox.information(self, '提示', f'第{rowNum+1}行品名错误')
                    return
                try:
                    批号 = self.ui.tableWidget.item(rowNum, 1).text()
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum+1}行批号错误')
                    return
            self.打印 = 打印机_基类_窗体(type='打印质检报告')
            self.打印.show()  # 直接打印
            self.打印.ui.pushButton.clicked.connect(
                lambda: self.PrintOK(type='打印质检报告', data=self.getRowData(rowNum=None)))
            self.打印.ui.pushButton_2.clicked.connect(
                lambda: self.PrintOK(type='打印质检报告预览', data=self.getRowData(rowNum=None)))
    def Del_Btn_Clicked(self):
        '''打印全部'''
        if not self.ui.tableWidget.rowCount():
            QMessageBox.information(self, '提示', '没有数据')
            return
        else:
            for rowNum in range(self.ui.tableWidget.rowCount()):
                品名 = self.ui.tableWidget.cellWidget(rowNum, 0).text()
                if not 品名:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行品名错误')
                    return
                品名 = self.ui.tableWidget.cellWidget(rowNum, 0).text()

                try:
                    执行标准 = self.ui.tableWidget.item(rowNum, 9).text()
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行执行标准错误')
                    return

                try:
                    批号 = self.ui.tableWidget.item(rowNum, 1).text()
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行批号错误')
                    return
                try:
                    标签装量 = self.ui.tableWidget.item(rowNum, 3).text()
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行错误')
                    return
                try:
                    标签数量 = int(self.ui.tableWidget.item(rowNum, 4).text())
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行错误')
                    return
                try:
                    规格 = self.ui.tableWidget.item(rowNum, 5).text()
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行错误')
                    return
                try:
                    产地 = self.ui.tableWidget.item(rowNum, 6).text()
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行错误')
                    return
                try:
                    保质期 = int(self.ui.tableWidget.item(rowNum, 7).text())
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行错误')
                    return
                try:
                    执行标准 = self.ui.tableWidget.item(rowNum, 9).text()
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行错误')
                    return
                try:
                    生产日期 = QDate.fromString(self.ui.tableWidget.item(rowNum, 7).text(), 'yyyy-MM-dd')
                except:
                    QMessageBox.information(self, '提示', f'第{rowNum + 1}行错误')
                    return
                self.打印 = 打印机_基类_窗体(type='打印全部')
                self.打印.show()  # 直接打印
                self.打印.ui.pushButton.clicked.connect(
                    lambda: self.PrintOK(type='打印全部', data=self.getRowData(rowNum=None)))
                self.打印.ui.pushButton_2.clicked.connect(
                    lambda: self.PrintOK(type='打印全部预览', data=self.getRowData(rowNum=None)))
#

if __name__=='__main__':
    app = QApplication(sys.argv)
    主窗口 = 办公室_账户管理_窗体()
    主窗口.show()

    sys.exit(app.exec())